<?php
namespace app\servergoods\logic;

use \app\manage\logic\BaseLogic;
use \think\Db;
use \app\manage\service\ApiBase;

// 商品微应用下的逻辑层
// dbXXXX : 不作为接口返回json数据，用于内部调用
class Goods extends BaseLogic
{
	protected $name = 'goods';
    protected $config = 'db_config_goods';
    protected $goodsModel = 'app\servergoods\model\Goods';
    protected $accountBookModel = 'app\servergoods\model\AccountBook';

    /*内部db查询商品详情*/
    public function dbOneGoodsInfo($data)
    {
        return $this->db()
                    ->where('id',$data['id'])
                    ->where('is_del','neq',2)
                    ->find();
    }

    /*内部根据id进行简单直接的db查询商品列表*/
    public function dbGoodsList($data)
    {
        return $this->db()
                    ->where('id','in',$data['id'])
                    ->where('is_del','neq',2)
                    ->select();
    }

    /*获取商品编码*/
    public function _getProductCode(): array 
    {
        $coding = 0;
        $config = config('coding');
        $action = $config[11]['goods'];
        if(function_exists($action)){
            $coding = $action();
        }
        return auto_return($coding);
    }


    /*亚数卖家发布商品*/
    public function yayiAddGoods($data): array
    {
        unset($data['app_id']);
        if(isset($data['imgs_urls'])){
            $imgUrls = explode(",", $data['imgs_urls']);
            $data['profile_pic'] = $data['profile_pic'] ? $data['profile_pic'] : $imgUrls[0];
        }
         
        $data['status'] = 0;
        $data['is_sell'] = 0;  //亚数  不可出售
           
        $data['search_fields']['cate_ids'] = logic('\app\servergoods\logic\GoodsCategory')->getParentIds(['cate_id'=>$data['cate_id']]);

        try{
            $res = $this->model($this->goodsModel)->save($data);
        }catch(\Exception $e){
            return server_err(null, '数据库错误' . $e->getMessage() );
        }
        $res && $res = $this->model($this->goodsModel)->id;

        return auto_return($res, '发布商品成功');
            
    }

    /*艺货后台发布商品*/
    public function yihuoAddGoods($data): array 
    {
        unset($data['app_id']);
        if(isset($data['imgs_urls'])){
            $imgUrls = explode(",", $data['imgs_urls']);
            $data['profile_pic'] = $data['profile_pic'] ? $data['profile_pic'] : $imgUrls[0];
        }
         
        $data['status'] = 1;
        $data['is_sell'] = 1;  
        $data['number'] = $data['origin_number'];
        $data['search_fields']['cate_ids'] = logic('\app\servergoods\logic\GoodsCategory')->getParentIds(['cate_id'=>$data['cate_id']]);
        $data['orther_info']['original_price'] = $data['price'];
        $data['orther_info']['original_orther_price'] = $data['orther_price'];
        try{
            $res = $this->model($this->goodsModel)->save($data);
        }catch(\Exception $e){
            return server_err(null, '数据库错误' . $e->getMessage() );
        }
        $res && $res = $this->model($this->goodsModel)->id;
        return auto_return($res, '发布商品成功');
    }

    
    /*亚数卖家编辑商品  审核失败时编辑藏品*/
    public function yayiEditGoods($data): array 
    {
        $allowField = $this->getEditFields(['user_id'=>$data['user_id']]);
        $allowField = $allowField ? $allowField : false;

        $_where['id'] = $data['id'];
        $_where['user_id'] = $data['user_id'];
        $_where['is_del'] = 0;
        $_where['status'] = 2;

        //如果修改了cate_id则修改search_fields字段里的cate_ids
        $info = $this->model($this->goodsModel)->where($_where)->find();
        
        $number = isset($data['number']) ? $data['number'] : $info['number'];
        $origin_number = isset($data['origin_number']) ? $data['origin_number'] : $info['origin_number'];
        if($number > $origin_number){
            return verify_err(null, '剩余数量不能大于原始数量');
        }

        if(isset($data['cate_id']) && $data['cate_id']){
            $search_fields = isset($data['search_fields']) ? $data['search_fields'] : $info['search_fields'];
            $search_fields['cate_ids'] = logic('\app\servergoods\logic\GoodsCategory')->getParentIds(['cate_id'=>$data['cate_id']]);
            $data['search_fields'] = $search_fields;
        }else{
            isset($data['search_fields']) && $data['search_fields']['cate_ids'] = $info['search_fields']['cate_ids'];
        }

        $data['status'] = 0;
        /*未处理json字段内部的更新  暂且对于json字段全部更新*/
        $res = $this->model($this->goodsModel)
                    ->allowField($allowField)
                    ->save($data,$_where);

        return auto_return($res,'编辑商品成功','编辑商品失败');
    }

    /*艺货卖家编辑商品*/
    public function yihuoEditGoods($data): array 
    {
        
        $_where['id'] = $data['id'];
        $_where['is_del'] = 0;

        //如果修改了cate_id则修改search_fields字段里的cate_ids
        $info = $this->model($this->goodsModel)->where($_where)->find();

        $number = isset($data['number']) ? $data['number'] : $info['number'];
        $origin_number = isset($data['origin_number']) ? $data['origin_number'] : $info['origin_number'];
        if($number > $origin_number){
            return verify_err(null, '剩余数量不能大于原始数量');
        }

        if(isset($data['cate_id']) && $data['cate_id']){
            $search_fields = isset($data['search_fields']) ? $data['search_fields'] : $info['search_fields'];
            $search_fields['cate_ids'] = logic('\app\servergoods\logic\GoodsCategory')->getParentIds(['cate_id'=>$data['cate_id']]);
            $data['search_fields'] = $search_fields;
        }else{
            isset($data['search_fields']) && $data['search_fields']['cate_ids'] = $info['search_fields']['cate_ids'];
        }
        $res = $this->model($this->goodsModel)
                    ->allowField(['goods_belonger_name','cate_id','title','authors','profile_pic','imgs_urls','imgs_ids','number','origin_number','price','orther_price','pay_method','pick_up_time','start_delivery_time','end_delivery_time','orther_info','desc','goods_attrs','search_fields','organization','latest_refund_time','img_desc','text_desc'])
                    ->save($data,$_where);

        return auto_return($res,'编辑商品成功','编辑商品失败');
    }

    /*根据不同的用户获取可编辑商品的字段信息*/
    public function getEditFields($data): array 
    {
        $fields = ['cate_id','title','imgs_urls','imgs_ids','price','desc','goods_attrs','orther_info','search_fields','status'];
        return $fields;
    }


    /*处理商品属性信息*/
    public function dealGoodsAttrs($attrsList, $goodsAttrs): array
    {
    	$attrsList = reset_array_key($attrsList,'en_name');
        $newGoodsAttrs = [];

    	foreach ($goodsAttrs as $k => &$v) {
            if(!isset($attrsList[$v['en_name']])){
                return verify_err(null, '失败！添加了一个不存在的属性');
            }
            $v = array_merge($v,$attrsList[$v['en_name']]);
            if(in_array($v['attr_type'], ['4'])){   //多选情况
                $newGoodsAttrs[$v['en_name']][] = $v; 
            }else{
                $newGoodsAttrs[$v['en_name']] = $v;
            }
    	}

        return auto_success($newGoodsAttrs);
    }

    /*获取搜索字段*/
    public function getSearchField($attrData): array
    {
        foreach ($attrData as $k => &$v) {
            $v = implode(",", $v);
            $v = ',' . $v . ',';
        }
    	return $attrData;
    }

    /*获取某商品所有详情 若该商品所属分类，该应用可看到，便可进行获取商品详情*/
    public function goodsDetail($data, $map = []): array
    {

        $_where['goods.id'] = $data['id'];
        isset($data['user_id']) && $_where['goods.user_id'] = $data['user_id'];

        $_where['goods.is_del'] = $map['is_del'] ?? ['neq',2];
        if(isset($map['status']) && $map['status'] !== ''){ $_where['goods.status'] = $map['status']; }
        if(isset($map['number']) && $map['number'] !== ''){ $_where['goods.number'] = $map['number']; }
        if(isset($map['is_sell']) && $map['is_sell'] !== ''){ $_where['goods.is_sell'] = $map['is_sell']; }

        if(isset($data['app_id'])){   //若卖家查看商品详情，则不传入app_id
            $manageAppId = ApiBase::getAppId();
            $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';
        }else{
            $_whereOr = true;
        }

        $res = Db::connect(config('db_config_goods'))
                ->view('goods',$data['fields'])
                ->view('goods_category',['name'=>'cate_name','app_id','other_app_read','is_public'],'goods.cate_id = goods_category.id','LEFT')
                ->where($_where)
                ->where($_whereOr)
                ->find();
        if($res){
            isset($res['orther_price']) && $res['orther_price'] = json_decode($res['orther_price'], true);
            isset($res['orther_info']) && $res['orther_info'] = json_decode($res['orther_info'], true);
            isset($res['goods_attrs']) && $res['goods_attrs'] = json_decode($res['goods_attrs'], true);
            if(isset($res['search_fields'])){
                $res['search_fields'] = json_decode($res['search_fields'], true);
                $res['cate_ids'] = array_reverse(explode(",", trim($res['search_fields']['cate_ids'], ",")));
            }
        }
        //增加访问次数
        $this->db()->alias('goods')->where($_where)->setInc('view_times');
    	return auto_return($res, '成功获取该商品详情', '获取商品详情失败');
        //if($res){ return auto_success($res); }else{ return auto_failure(NULL, '获取商品信息失败'); }
    }

    /*管理员删除一个或多个商品*/
    public function manageDelGoods($data): array 
    {

        !is_array($data) && $data['id'] = [$data['id']]; 
        $_where['goods.id'] = ['in',$data['id']];
        $_where['goods.is_del'] = ['neq',2];
        $saveData['goods.is_del'] = 2;

        //左链接分类表，对app_id进行验证操作
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        $res = $this->db()
                    ->alias('goods')
                    ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                    ->where($_where)
                    ->where($_whereOr)
                    ->update($saveData);

        return auto_return($res);
    }

    /*商家删除某个商品(删除时一并下架)*/
    public function sellerDelGoods($data): array 
    {
        $_where['id'] = $data['id'];
        $_where['is_del'] = 0;
        $saveData['is_del'] = 1;
        $saveData['status'] = 3;
        
        $res = $this->db()
                    ->where($_where)
                    ->update($saveData);

        return auto_return($res);
    }

    /*卖家下架一个商品*/
    public function sellerSoldOutOne($data): array 
    {
        $_where['id'] = $data['id'];
        $_where['is_del'] = 0;
        $_where['status'] = ['in',['1','4']];
        $saveData['status'] = 3;
        $res = $this->model($this->goodsModel)->save($saveData, $_where);

        return auto_return($res);
    }

    /*根据条件获取商品总量*/
    public function goodsCount($map): array 
    {
        //左链接分类表，对app_id进行验证操作
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $map['app_id'] ? true : 'goods_category.`app_id`=' . $map['app_id'] . ' OR FIND_IN_SET(' . $map['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        $_where['goods.is_del'] = isset($map['is_del']) ? $map['is_del'] : ['neq',2];
        isset($map['status']) && $_where['goods.status'] = $map['status'];
        isset($map['user_id']) && $_where['goods.user_id'] = $map['user_id'];

        $res = $this->db()
                    ->alias('goods')
                    ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                    ->where($_where)
                    ->where($_whereOr)
                    ->count();
        return auto_success($res);
    }

    /*管理员批量操作（审核、下架）商品*/
    public function batchOperaGoods($data, $operate): array 
    {
        //左链接分类表，对app_id进行验证操作
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        $_where['goods.id'] = ['in',$data['id']];
        $_where['goods.is_del'] = ['neq',2];

        if($operate == 'manageBatchAuditGoods'){
            $_where['goods.status'] = 0;
        }elseif($operate == 'manageBatchSoldOutGoods'){
            $_where['goods.status'] = ['in',['1','4']];
        }

        $saveData['goods.status'] = $data['status'];
        $res = $this->db()
                ->alias('goods')
                ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                ->where($_where)
                ->where($_whereOr)
                ->update($saveData);

        return auto_return($res);
    }

    /*获取商品列表 */
    public function goodsList($data): array 
    {

        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        if( isset($data['user_id']) && $data['user_id'] ) $_where['goods.user_id'] = $data['user_id']; 
        if( isset($data['number']) && $data['number'] ) $_where['goods.number'] = $data['number'];
        if( isset($data['keywords']) && $data['keywords'] ) $_where['goods.title|goods.authors'] = ['like', '%' . $data['keywords'] . '%'];
        $_where['goods.status'] = $data['status'] ?? 1; 
        $_where['goods.is_del'] = $data['is_del'] ?? ['eq',0]; 
        $data['price_start'] = $data['price_start'] ?? 0;
        $data['fields'] = $data['fields'] ?? '*,origin_number-number AS sales';

        //搜索字段
        if(isset($data['is_sell'])) $_where['goods.is_sell'] = $data['is_sell'];
        if(isset($data['cate_id']) && $data['cate_id']) $_where['goods.search_fields$.cate_ids'] = ['like','%,'.$data['cate_id'].',%'];
        $_recommendWhere = isset($data['recommend']) ? 'FIND_IN_SET(\'' . $data['recommend'] . '\',goods.`recommend`)' : true;

        if(isset($data['price_start']) && isset($data['price_end']) && isset($data['symbol']) && in_array($data['symbol'], ['elt','between','egt'])){
            if(!$data['price_start'] && !$data['price_end']){ return verify_err(null, 'symbol存在时，请传入price_start或price_end'); }
            if($data['symbol'] == 'elt'){
                $_where['goods.price'] = ['elt',$data['price_end']];
            }elseif($data['symbol'] == 'between'){
                $_where['goods.price'] = ['between',[ $data['price_start'],$data['price_end'] ]];
            }else{
                $_where['goods.price'] = ['egt',$data['price_start']];
            }
        }
        //对商品的可搜索字段进行搜索
        if(isset($data['search_fields']) && $data['search_fields']){
            foreach ($data['search_fields'] as $k => $v) {  // 例 search_fields:[{"en_name":"pattern","value":"古代"}]
                if(isset($v['en_name'],$v['value']) && $v['en_name'] && $v['value']){
                    $searchFields = 'goods.search_fields$.' . $v['en_name'];
                    $_where[$searchFields] = ['like','%,'.$v['value'].',%'];
                }
            }
        }
        if(isset($data['order']) && $data['order'] == 'sales'){
            $order = 'sales DESC, goods.id DESC';
        }else{
            $order = 'goods.id DESC';
        }            
        $res = Db::connect(config('db_config_goods'))
                ->view('goods',$data['fields'])
                ->view('goods_category',['name'=>'cate_name','app_id','other_app_read','is_public'],'goods.cate_id = goods_category.id','LEFT')
                ->where($_where)
                ->where($_recommendWhere)
                ->where($_whereOr)
                ->order($order)
                ->paginate(null,false,['page'=>$data['page'],'list_rows'=>$data['listRows']])
                ->toArray();
        if($res['total'] > 0){
            foreach ($res['data'] as $k => &$v) {
                isset($v['goods_attrs']) && $v['goods_attrs'] = json_decode($v['goods_attrs'], true);
                isset($v['orther_price']) && $v['orther_price'] = json_decode($v['orther_price'], true);
                isset($v['orther_info']) && $v['orther_info'] = json_decode($v['orther_info'], true);
                isset($v['search_fields']) && $v['search_fields'] = json_decode($v['search_fields'], true);
            }
        }

        return auto_return_page($res);
    }

    /*执行商品售空操作*/
    public function outOfStock($data): array 
    {
        $_where['goods.is_del'] = 0;
        $_where['goods.status'] = 1;
        $_where['goods.number'] = 0;
        $saveData['goods.status'] = 4;

        //左链接分类表，对app_id进行验证操作
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        $res = $this->db()
                    ->alias('goods')
                    ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                    ->where($_where)
                    ->where($_whereOr)
                    ->update($saveData);
                    
        return auto_return($res);
    }

    /*管理员推荐某个商品*/
    public function recommend($data): array 
    {
        $_where['goods.id'] = $data['id'];
        $_where['goods.status'] = 1;
        $_where['goods.is_del'] = 0;
        $saveData['goods.recommend'] = trim($data['recommend'],",");
        /*追加式推荐*/
        /*if($data['recommend'] == ''){
            $saveData['goods.recommend'] = $data['recommend'];
        }else{
            //追加推荐位
            $goodsInfo = $this->db()->where($_where)->find();
            $saveData['goods.recommend'] = $goodsInfo['recommend'] ? implode(",", array_unique(array_merge(explode(",", $goodsInfo['recommend']), explode(",", $data['recommend'])))) : $data['recommend'];
        }*/

        //左链接分类表，对app_id进行验证操作
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        $res = $this->db()
                    ->alias('goods')
                    ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                    ->where($_where)
                    ->where($_whereOr)
                    ->update($saveData);
        return auto_return($res);
    }

    /*首先获取相对应的最大值和最小值*/
    /*获取价格段前的处理
        1、最小值向下取整 （精确到元）
        2、最大值向上取整 （精确到元）
        3、最大值与最小值间隔太小，直接取一个价格段：最小值-最大值
    */
    /*获取价格段  价格段中的三个值的获取公式分别为：(结果中不包含以上和以下。有模的将得到6段，无模除尽的得到5段)
        1、间隔： (最大值-最小值)/5->进行向上取整  <ceil — 进一法取整>
        2、顶部的值： 间隔 * （最大值/间隔->向下取整 + 最大值模于间隔 ？ 1 ：0 ） <floor — 舍去法取整>
        3、底部的值： 间隔 * （最低值/间隔->向下取整）
    */
    /*获取商品价格的筛选项*/
    public function getPriceFilter($data): array 
    {
        $_where['goods.status'] = 1;
        $_where['goods.is_del'] = 0;
        $_where['goods.number'] = ['gt', 0];
        $_where['is_sell'] = $data['is_sell'];
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        $price = $this->db()
                    ->alias('goods')
                    ->field(['max(price)'=>'max_price','min(price)'=>'min_price'])
                    ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                    ->where($_whereOr)
                    ->where($_where)
                    ->find();
        $minPrice = bcsub($price['min_price'], $price['min_price']%100);
        if($price['max_price']%100){ 
            $maxPrice = bcadd($price['max_price'], bcsub(100, $price['max_price']%100));
        }else{
            $maxPrice = $price['max_price'];
        }
        $res = [];
        if(bcsub($maxPrice, $minPrice) < 100){
            $res[] = ['price_start'=>$minPrice,'price_end'=>$maxPrice,'symbol'=>'between'];
            return auto_success($res, '成功获取价格筛选项', '获取价格筛选项失败');
        }
        //间隔向上取整 保证结果后两位为0
        $d = ceil( bcdiv(bcsub($maxPrice, $minPrice), 5) );  
        if($d%100){
            $d = bcadd($d, bcsub(100, $d%100));
        }
        $topMod = $maxPrice%$d ? 1 : 0;
        $top =  bcmul($d, bcadd(floor( bcdiv($maxPrice, $d) ),$topMod));
        $bottom =  bcmul($d, floor( bcdiv($minPrice, $d) ));
        //组装结果
        $res[] = ['price_start'=>$bottom,'price_end'=>bcadd($bottom, $d),'symbol'=>'between'];
        $res[] = ['price_start'=>bcadd($bottom, $d),'price_end'=>bcadd($bottom, bcmul($d, 2)),'symbol'=>'between'];
        $res[] = ['price_start'=>bcadd($bottom, bcmul($d, 2)),'price_end'=>bcadd($bottom, bcmul($d, 3)),'symbol'=>'between'];
        $res[] = ['price_start'=>bcadd($bottom, bcmul($d, 3)),'price_end'=>bcadd($bottom, bcmul($d, 4)),'symbol'=>'between'];
        $res[] = ['price_start'=>bcadd($bottom, bcmul($d, 4)),'price_end'=>bcadd($bottom, bcmul($d, 5)),'symbol'=>'between'];
        /*if($topMod){ $res[] = ['price_start'=>bcadd($bottom, bcmul($d, 5)),'price_end'=>bcadd($bottom, bcmul($d, 6)),'symbol'=>'between']; }*/
        if($maxPrice > bcadd($bottom, bcmul($d, 5))){
            $res[] = ['price_start'=>bcadd($bottom, bcmul($d, 5)),'price_end'=>bcadd($bottom, bcmul($d, 6)),'symbol'=>'between'];
        }
        return auto_success($res, '成功获取价格筛选项', '获取价格筛选项失败');
    }

    /*前台获取某推荐位下的商品列表*/
    public function getRecommendList($data): array 
    {
        //$_where['goods.recommend'] = $data['recommend'];
        $_recommendWhere = 'FIND_IN_SET(\'' . $data['recommend'] . '\',goods.`recommend`)';
        $_where['goods.status'] = 1;
        $_where['goods.is_del'] = 0;
        $_where['goods.number'] = ['gt', 0];
        $data['cate_id'] && $_where['goods.search_fields$.cate_ids'] = ['like','%,'.$data['cate_id'].',%'];
        if(isset($data['is_sell']) && $data['is_sell'] !== '') $_where['goods.is_sell'] = $data['is_sell'];
        //左链接分类表，对app_id进行验证操作
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';

        if(isset($data['isPage']) && $data['isPage']){   //分页列表数据
            $resPage = Db::connect(config('db_config_goods'))
                ->view('goods','*')
                ->view('goods_category',['name'=>'cate_name','app_id','other_app_read','is_public'],'goods.cate_id = goods_category.id','LEFT')
                ->where($_where)
                ->where($_recommendWhere)
                ->where($_whereOr)
                ->order('goods.id','desc')
                ->paginate(null,false,['page'=>$data['page'],'list_rows'=>$data['listRows']])
                ->toArray();
            if($resPage['total'] > 0){
                foreach ($resPage['data'] as $k => &$v) {
                    isset($v['goods_attrs']) && $v['goods_attrs'] = json_decode($v['goods_attrs'], true);
                    isset($v['orther_price']) && $v['orther_price'] = json_decode($v['orther_price'], true);
                    isset($v['orther_info']) && $v['orther_info'] = json_decode($v['orther_info'], true);
                    isset($v['search_fields']) && $v['search_fields'] = json_decode($v['search_fields'], true);
                }
            }
            return auto_return_page($resPage);    
        }else{                                           //无分页
            $res = Db::connect(config('db_config_goods'))
                ->view('goods','*')
                ->view('goods_category',['name'=>'cate_name','app_id','other_app_read','is_public'],'goods.cate_id = goods_category.id','LEFT')
                ->where($_where)
                ->where($_recommendWhere)
                ->where($_whereOr)
                ->order('goods.id','desc')
                ->limit($data['limit'])
                ->select();
            if($res){
                foreach ($res as $k => &$v) {
                    isset($v['goods_attrs']) && $v['goods_attrs'] = json_decode($v['goods_attrs'], true);
                    isset($v['orther_price']) && $v['orther_price'] = json_decode($v['orther_price'], true);
                    isset($v['orther_info']) && $v['orther_info'] = json_decode($v['orther_info'], true);
                    isset($v['search_fields']) && $v['search_fields'] = json_decode($v['search_fields'], true);
                }
            }
            return auto_return($res, '成功获取商品列表');
        } 
    }
    /*前台根据商品ids简单获取商品列表-中间方法调取*/
    public function getListByIds($data): array 
    {
        $_where['goods.id'] = ['in', $data['goods_ids']];
        $_where['goods.status'] = 1;
        $_where['goods.is_del'] = 0;
        $_where['goods.number'] = ['gt', 0];
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';
        $res = Db::connect(config('db_config_goods'))
                ->view('goods','*')
                ->view('goods_category',['name'=>'cate_name','app_id','other_app_read','is_public'],'goods.cate_id = goods_category.id','LEFT')
                ->where($_where)
                ->where($_whereOr)
                ->order('goods.id','desc')
                ->select();
        if($res){
            foreach ($res as $k => &$v) {
                isset($v['goods_attrs']) && $v['goods_attrs'] = json_decode($v['goods_attrs'], true);
                isset($v['orther_price']) && $v['orther_price'] = json_decode($v['orther_price'], true);
                isset($v['orther_info']) && $v['orther_info'] = json_decode($v['orther_info'], true);
                isset($v['search_fields']) && $v['search_fields'] = json_decode($v['search_fields'], true);
            }
        }
        return auto_return($res);
    }
    /*艺货 - 获取艺术家的在售商品 不分页 只要为发布的商品，一律获取*/
    public function getArtistGoods($data): array 
    {
        $_where['goods_belonger_name'] = $data['goods_belonger_name'];
        if($data['keywords']){
            $_where['goods.title'] = ['like', '%' . $data['keywords'] . '%'];
        }
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';
        $res = Db::connect(config('db_config_goods'))
                ->view('goods','*')
                ->view('goods_category',['name'=>'cate_name','app_id','other_app_read','is_public'],'goods.cate_id = goods_category.id','LEFT')
                ->where($_where)
                ->where($_whereOr)
                ->order('goods.id','desc')
                ->paginate(null,false,['page'=>$data['page'],'list_rows'=>$data['listRows']])
                ->toArray();
        return auto_return_page($res);
    }

    /*艺货 - 添加一条与艺术家的账单*/
    public function addAccountBook($data): array 
    {
        $data['sign_settlement_user_info'] = [];
        $res = $this->model($this->accountBookModel)->save($data);
        return auto_return($res, '成功添加账单', '添加账单失败');
    }

    /*艺货 - 标注该账单已结算*/
    public function signSettlement($data): array 
    {
        $saveData['is_settlement'] = 1;
        $saveData['sign_settlement_user_info'] = $data['sign_settlement_user_info'];
        $_where['id'] = $data['id'];
        $_where['is_settlement'] = 0;
        $res = $this->model($this->accountBookModel)->save($saveData, $_where);
        return auto_return($res, '成功标记为已结算');
    }

    /*内部获取我的账单分页数据*/
    protected function _myAccountBookList($data, bool $is_page_list = true): array 
    {
        if(isset($data['goods_id']) && $data['goods_id']){ $_where['account_book.goods_id'] = $data['goods_id']; }
        if(isset($data['time'])){
            $threeMonthTime = mktime(0, 0, 0, date("m")-3, date("d"), date("Y"));
            if($data['time'] == 'threeMonthAgo'){   
                $_where['account_book.create_time'] = ['lt',$threeMonthTime];    //3个月以前
            }elseif($data['time'] == 'threeMonth'){   
                $_where['account_book.create_time'] = ['gt',$threeMonthTime];    //3个月之内
            }
        }
        $_where['goods.goods_belonger_name'] = $data['goods_belonger_name'];
        if($is_page_list){
            $res = Db::connect(config('db_config_goods'))
                ->view('account_book','*')
                ->view('goods',['goods_belonger_name'],'goods.id = account_book.goods_id','LEFT')
                ->where($_where)
                ->order('id','desc')
                ->paginate(null,false,['page'=>$data['page'],'list_rows'=>$data['listRows']])
                ->toArray();
            if($res['total'] > 0){
                foreach ($res['data'] as $k => &$v) {
                    $v['create_user_info'] = json_decode($v['create_user_info'], true);
                    $v['sign_settlement_user_info'] = json_decode($v['sign_settlement_user_info'], true);
                }
            }
            return auto_return_page($res);
        }else{
            $res = Db::connect(config('db_config_goods'))
                ->view('account_book','*')
                ->view('goods',['goods_belonger_name'],'goods.id = account_book.goods_id','LEFT')
                ->where($_where)
                ->order('id','desc')
                ->select();
            if($res){
                foreach ($res as $k => &$v) {
                    $v['create_user_info'] = json_decode($v['create_user_info'], true);
                    $v['sign_settlement_user_info'] = json_decode($v['sign_settlement_user_info'], true);
                }
            }
            return auto_return($res);
        }
    }

    /*艺货后台-获取所有账单分页数据*/
    public function allAccountBookList($data): array 
    {
        if($data['keywords']){
            $_where['goods.title|goods.goods_belonger_name|ab.remark'] = ['like', '%' . $data['keywords'] . '%'];
        }else{
            $_where = true;
        }
        $res = $this->model($this->accountBookModel)
                ->alias('ab')
                ->field('ab.*,goods.title,goods.goods_belonger_name')
                ->join('goods', 'goods.id = ab.goods_id', 'LEFT')
                ->where($_where)
                ->order('ab.id DESC')
                ->paginate(null,false,['page'=>$data['page'],'list_rows'=>$data['listRows']])
                ->toArray();
        return auto_return_page($res);
    }

    /*艺货前台-获取我艺术家身份的所有账单*/
    public function myAccountBookList($data): array 
    {
        return $this->_myAccountBookList($data, true);
    }

    /*艺货前台-获取我艺术家某件商品的所有账单 不分页*/
    public function myGoodsAccountBookList($data): array 
    {
        return $this->_myAccountBookList($data, false);
    }

    /*多个商品数量(剩余数量)-n   下订单前*/
    public function descGoodsNumber($data): array 
    {
        //检验所有的商品都是通过审核的状态
        $goodsIds = array_column($data['goods_info'], 'id');
        $_where['id'] = ['in', $goodsIds];
        $_where['status'] = 1;
        $goodsList = $this->db()->where($_where)->select();
        $goodsList = reset_array_key($goodsList, 'id');
        if(count($goodsList) != count($goodsIds)){ return verify_err(null, '有未通过的商品');  }
        //整理更改数据
        $saveAllData = [];
        foreach ($data['goods_info'] as $k => $v) {
            if($goodsList[$v['id']]['number'] < $v['number']){
                return verify_err(null, '商品【' . $goodsList[$v['id']]['title'] . '】数量不足，请刷新重试');
            }
            $oneSave['id'] = $v['id'];
            $oneSave['number'] = ['exp', 'number-' . $v['number']];
            $saveAllData[] = $oneSave;
        }
        /*开启事务*/
        $this->db()->startTrans();
        try{
            $res = $this->model($this->goodsModel)->saveAll($saveAllData);
            $this->db()->commit();
        }catch(\Exception $e){
            $this->db()->rollback();
            return server_err(null, '数据库错误' . $e->getMessage());
        }
        return auto_success($res, '成功减少商品数量');
    }

    /*多个商品数量（剩余数量）+n  取消订单以及订单超时时*/
    public function addGoodsNumber($data): array 
    {
        //检验所有的商品都是通过审核的状态
        $goodsIds = array_column($data['goods_info'], 'id');
        $_where['id'] = ['in', $goodsIds];
        $_where['status'] = 1;
        $counts = $this->model($this->goodsModel)->where($_where)->count();
        if($counts != count($goodsIds)){ return verify_err(null, '有未通过的商品');  }
        //整理更改数据
        $saveAllData = [];
        foreach ($data['goods_info'] as $k => $v) {
            $oneSave['id'] = $v['id'];
            $oneSave['number'] = ['exp', 'number+' . $v['number']];
            $saveAllData[] = $oneSave;
        }
        $res = $this->model($this->goodsModel)->saveAll($saveAllData);
        return auto_return($res, '成功增加商品数量');
    }
    /*后台给某一个商品改价(人民币/亚数币)或增加库存*/
    public function changePriceNumber($data): array 
    {
        $_where['goods.is_del'] = 0; 
        $_where['goods.id'] = $data['id'];
        $manageAppId = ApiBase::getAppId();
        $_whereOr = $manageAppId == $data['app_id'] ? true : 'goods_category.`app_id`=' . $data['app_id'] . ' OR FIND_IN_SET(' . $data['app_id'] . ',`other_app_read`) OR goods_category.is_public = 1';
        if($data['price']){ $saveData['price'] = $data['price']; }
        if($data['currency']){ $saveData['orther_price'] = json_encode(['currency'=>$data['currency']]); }
        if($data['add_number']){ 
            $saveData['number'] = ['exp', 'number+' . $data['add_number']]; 
            $saveData['origin_number'] = ['exp', 'origin_number+' . $data['add_number']]; 
        }
        $res = $this->model($this->goodsModel)
                    ->alias('goods')
                    ->join('goods_category', 'goods_category.id = goods.cate_id', 'LEFT')
                    ->where($_whereOr)
                    ->where($_where)
                    ->update($saveData);
        return auto_return($res);
    }

    /*批量修改人民币价格  艺货在售商品
        UPDATE `tp_goods` SET orther_price = JSON_SET(orther_price, '$.currency', CAST(JSON_EXTRACT(orther_price, '$.currency') AS UNSIGNED)*2),price = price*2 WHERE id IN (10,11,12)
        这里进行两个价格的修改 不传倍数则默认为1
    */
    //这里无法进行做左连接商品分类表
    public function batchChangePrice($data): array 
    {
        $_where['is_del'] = 0;
        $_where['status'] = 1;
        $_where['is_sell'] = 1;
        if(isset($data['cate_id']) && $data['cate_id']) $_where['search_fields$.cate_ids'] = ['like','%,'.$data['cate_id'].',%'];
        
        $data['allCount'] = 0;
        $data['affectCount'] = 0;
        $res = $this->db()
                    ->where($_where)
                    ->chunk(100, function($goodsList)use(&$data){
                        $goodsIds = array_column($goodsList, 'id');
                        $data['allCount'] = bcadd($data['allCount'], count($goodsIds));
                        $changeIds = '(' . implode(",", $goodsIds) . ')';
                        //拼接sql语句
                        $changePriceSql = "update tp_goods set orther_price = JSON_SET(orther_price,'$.currency', CAST(JSON_EXTRACT(orther_price, '$.currency') AS UNSIGNED)*" . $data['currency_multiple'] . "),price = price*" . $data['multiple'] . " where id in " . $changeIds;
                        Db::connect(config('db_config_goods'))->query($changePriceSql);
                        $count = Db::connect(config('db_config_goods'))->query("select row_count() as row_count");
                        $data['affectCount'] = bcadd($data['affectCount'], $count[0]['row_count']);   //成功修改的条数
                    });
        $failureCount = bcsub($data['allCount'], $data['affectCount']);
        if($failureCount){
            return verify_err($res, '共' . $data['allCount'] . '个商品,失败个数：'. $failureCount . '个');
        }else{
            return auto_success($res, '共' . $data['allCount'] . '个商品,全部修改成功');
        }
    }
    /*一周新增商品/总商品数量/在售商品数量*/
    public function goodsIncreTendency($data): array 
    {
        $dbDateFormat = $data['dbDateFormat'];
        $Db = \think\Db::connect(config('db_config_goods'));
        $weekSql = "select count(*) as counts, FROM_UNIXTIME(create_time, '$dbDateFormat') as create_time_date from tp_goods where create_time > UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL 1 WEEK)) group by create_time_date";
        $queryRes = $Db->query($weekSql);
        $weeks = week_key_array($data['dateFormat']);
        $delQueryRes = [];
        foreach ($queryRes as $k => $v) {
            $delQueryRes[$v['create_time_date']] = $v['counts'];
        }
        $weekIncre = array_merge($weeks, $delQueryRes);
        $newWeekIncre = [];
        foreach ($weekIncre as $k => $v) {
            $one['date'] = $k;
            $one['value'] = $v;
            $newWeekIncre[] = $one;
        }
        $res['weekIncre'] = $newWeekIncre;
        $res['is_sell_total'] = $this->db()->where(['is_sell'=>1,'status'=>1,'is_del'=>0])->count();
        $res['total'] = $this->db()->count();
        return auto_return($res);
    }


}